local lanes = require "lanes"
local json = require "cjson"
local config = require "config"
local datasource = config.mysql.data
local username = config.mysql.user
local password = config.mysql.auth
local host = config.mysql.host
local port = config.mysql.port

local function execute(mysql, msg)
    local method = msg.method
    if not method then
        return
    end

    local param = string.split(msg.method, ".", 2)
    local ok, chunk = pcall(require, "log." .. param[1])
    if not ok then
        return
    end

    if #param < 2 then
        return
    end

    if type(chunk) ~= "table" then
        return
    end

    local func = chunk[param[2]]
    if not func then
        return
    end

    return mysql.execute(func, msg)
end

local function processor(linda, idx)
    local lanes = require "lanes"
    local mysql = require "utils.mysql"

    while true do
        if cancel_test() then
            return
        end

        local ok, failmsg = mysql.create(datasource, username, password, host, port)
        if ok then
            break
        end

        spdlog.error("logger", "luasql_failmsg : " .. failmsg)
        lanes.sleep(3)
    end

    spdlog.debug("logger", "[%s:%s %s#%d] processor start ...", host, port, datasource, idx)
    while not cancel_test() do repeat
        local key, rpc = linda:receive(3.0, "logger")
        if key ~= "logger" then
            break
        end

        local id, msg = table.unpack(rpc)
        if not id or not msg then
            break
        end

        execute(mysql, msg)
    until true end

    mysql.destory()
    spdlog.debug("logger", "[%s:%s %s##%d] processor quit ...", host, port, datasource, idx)
end

-------------------------------------------------------------------------------
---! 对外接口
----------------------------------------------------------------------ILE_D:read_common_data---------
LOG_D = {}

function LOG_D:write_login_log(type, action, user_ob, para1, para2, para3, memo)
    local userid = user_ob:get_id()
    local stage = user_ob:get_stage_level()
    local account = user_ob:query_temp("loginInfo", "userName") or ""
    local channel = user_ob:query_temp("loginInfo", "source") or ""

    local rpc = {}
    rpc.method = "login.write"
    rpc.data = table.pack(type, action, userid, account, channel, stage, para1, para2, para3, memo)
    THREAD_D:post("logger", rpc)
end

function LOG_D:write_online_log(user_online, temp_online, user_loading)
    local rpc = {}
    rpc.method = "online.write"
    rpc.data = table.pack(user_online, temp_online, user_loading)
    THREAD_D:post("logger", rpc)
end

-------------------------------------------------------------------------------
---! 启动接口
-------------------------------------------------------------------------------
register_post_init(function()
    for idx = 1, 1 do
        SERVICE_D:create("log", processor, idx)
    end
end)
